package titan.utils;

import java.util.regex.Pattern;

/**
 * Class composed of methods that enable the validation of text fields, 
 * such as name, URL and email via regular expressions
 */
public abstract class TextValidator {
	private static final String name = "([\\p{L}\\p{M}*]|[0-9])([\\-\\._]?([\\p{L}\\p{M}*]|[0-9]))*"; //$NON-NLS-1$
	private static final String ip = "(25[0-4]|2[0-4]\\d|[0-1]?\\d?[1-9])(\\.(25[0-4]|2[0-4]\\d|[0-1]?\\d?\\d)){3}"; //$NON-NLS-1$
	private static final String host = "[\\p{Alpha}](\\p{Alnum}|(\\-\\p{Alnum}))*(\\.[\\p{Alpha}](\\p{Alnum}|(\\-\\p{Alnum}))*)*"; //$NON-NLS-1$

	/**
	 * Test to validate a name 
	 * @param text - the name
	 * @return true if it's a valid name and false otherwise
	 */
	public static boolean isValidFileName(String text) {
		return text.replaceAll("[\\\\/\\*\\?<>\\|\"\\:;]", "").compareTo(text) == 0; //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Test to validate a host 
	 * @param text - the host
	 * @return true if it's a valid host and false otherwise
	 */
	public static boolean isValidHost(String text) {
		if(text.replaceAll("[^0-9\\.]", "").compareTo(text) == 0) //$NON-NLS-1$ //$NON-NLS-2$
			return isValidIP(text);
		else
			return isValidHostName(text);
	}

	/**
	 * Test to validate a host name 
	 * @param text - the host name
	 * @return true if it's a valid host name and false otherwise
	 */
	private static boolean isValidHostName(String text) {
		return Pattern.matches("^"+host+"$", text); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Test to validate an IP address 
	 * @param text - the IP address
	 * @return true if it's a valid IP address and false otherwise
	 */
	public static boolean isValidIP(String text) {
		return Pattern.matches("^"+ip+"$", text); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Test to validate an URL 
	 * @param text - the URL
	 * @return true if it's a valid URL and false otherwise
	 */
	public static boolean isValidUrl(String text) {
		return Pattern.matches("^http\\://"+ //$NON-NLS-1$
				"(("+ip+")|("+host+"))"+ //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				"(\\:[\\d]{1,4}?)?"+ //$NON-NLS-1$
				"(/[\\w\\.\\-%]+)*/?$", text); //$NON-NLS-1$
	}

	/**
	 * Test to validate a port 
	 * @param text - the port
	 * @return true if it's a valid port and false otherwise
	 */
	public static boolean isValidPort(String text) {
		return Pattern.matches("^[\\d]{1,4}$", text); //$NON-NLS-1$
	}

	/**
	 * Test to validate a full URL
	 * @param text - the URL
	 * @return true if it's a valid full URL and false otherwise
	 */
	public static boolean isValidFullUrl(String text) {
		int lastSlashIndex = text.lastIndexOf("/"); //$NON-NLS-1$
		if(lastSlashIndex > 0){
			String begin = text.substring(0, lastSlashIndex);
			if(!isValidUrl(begin))
				return false;
			return true; //accept url end as valid always
		}
		return false;
	}

	/**
	 * Test to validate an e-mail
	 * @param text - the e-mail
	 * @return true if it's a valid e-mail and false otherwise
	 */
	public static boolean isValidEmail(String text) {
		return Pattern.matches("^[\\w\\-\\.+]+\\@([\\p{Alnum}][\\p{Alnum}\\-]*\\.)+[\\p{Alpha}]{2,}$", text); //$NON-NLS-1$
	}

	/**
	 * Test to validate an object name
	 * @param text - the string to be validated
	 * @return true if it's a valid object name and false otherwise
	 */
	public static boolean isValidUObject(String text) {
		final String object = "_*[\\p{L}\\p{M}*](([\\p{L}\\p{M}*]|[0-9]|_)|(\\-([\\p{L}\\p{M}*]|[0-9])))*"; //$NON-NLS-1$
		return Pattern.matches("^"+object+"$", text); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 *Test to validate a dotted alphanumeric
	 * @param text - the string to be validated
	 * @return true if it's a valid dotted alphanumeric and false otherwise
	 */
	public static boolean isValidDottedUAlnum(String text) {
		return Pattern.matches("^"+name+"$", text); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Test to validate spaced alphanumeric
	 * @param text - the string to be validated
	 * @return true if it's a valid spaced alphanumeric and false otherwise
	 */
	public static boolean isValidSpacedUAlnum(String text) {
		return Pattern.matches("^(("+name+")\\p{Space})*"+name+"$", text); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
	}

	/**
	 * Test to validate a sentence
	 * @param text - the string to be validated
	 * @return true if it's a valid sentence and false otherwise
	 */
	public static boolean isValidUSentence(String text) {
		final String name = "([\\p{L}\\p{M}*]|[0-9])([\\-\\._/]?([\\p{L}\\p{M}*]|[0-9]))*"; //$NON-NLS-1$
		final String punct_opt = "(([!,\\.\\:;\\?])|(\\?!)|(\\.\\.\\.))?"; //$NON-NLS-1$
		return Pattern.matches("^(("+name+")"+punct_opt+"\\p{Space})*"+name+punct_opt+"$", text); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
	}
}
